const express = require('express');
const app = express();
const fs = require('fs');
const json5 = require('json5');

const dirHome = require('os').homedir();

const { verify } = require('./src/middlewares/ident.js');

/**
 * 读取配置文件
 */
const dirConfig = `${dirHome}/.spbs`;
const configText = fs.readFileSync(`${dirConfig}/config.json5`);
const config = json5.parse(configText);
app.set('config', config);

const identText = fs.readFileSync(`${dirConfig}/ident.json5`);
const idents = json5.parse(identText);
app.set('idents', idents);

/**
 * 创建日志目录
 */
const dirLogs = `${dirConfig}/logs`;
try {
  fs.mkdirSync(dirLogs);
} catch (e) {
  // 文件已存在无所谓，否则报错退出
  if (e.code != 'EEXIST') {
    throw e;
  }
}

/**
 * lastBeats
 * 存储每个源的最后心跳数据
 * 用当前时间戳初始化
 */
let lastBeats = ((idents) => {
  let beats = {};
  idents.forEach((v) => {
    beats[v.source] = Math.floor(new Date() / 1000);
  });
  return beats;
})(idents);

/**
 * 将初始心跳追加到相应文件，文件不存在时自动新建
 */
const logBeatStart = (sourceName, timestamp) => {
  const file = `${dirLogs}/${sourceName}`;
  fs.appendFile(file, `\n${timestamp}`, (err) => {
    if (err) {
      console.log(err);
    }
  });
};

// 记录系统启动时的伪初始心跳
Object.entries(lastBeats).forEach(([k, v]) => {
  logBeatStart(k, v);
});

// 心跳检测循环，10秒检测一次
setInterval(() => {
  const ctime = new Date() / 1000;
  idents.forEach((v) => {
    if (ctime - lastBeats[v.source] > v.threshold) {
      // TODO 超时处理
    }
  });
}, 10000);

app.get('/', verify, (_req, res) => {
  res.send('Hello, SPBS!');
});

// 保存客户端发来的心跳作为最后心跳
app.post('/beat', verify, (req, res) => {
  lastBeats[req.heart.source] = Math.floor(new Date() / 1000);
  res.send({ status: 0 });
});

app.listen(config.port, () => {
  console.log(`SPBS start at ${config.port}`);
});
